#pragma once 

class State;
class PendingState;
class RunningState;
class Communicator;
class Shader;
class LineRenderer;
class PointRenderer;
class BoxPrimitive;
class ParticleSystem;

class Game
{
public:
	enum GameType { CLIENT, SERVER, SINGLE};
	static Game* create(GameType);
	static Game* getInstance();
    virtual ~Game();
    
    // TODO: rewrite to not be static&upd clients, because class now singleton 
    static glm::dvec2 windowDim;
    static glm::mat4& getPerspMatrix();
    static glm::mat4& getOrthoMatrix();
	Communicator* communicator;
	GameType game_type;
	static GLFWwindow* window;
	State* getCurrentState();
	RunningState* getRunningState();
	LineRenderer* lineRenderer;
	PointRenderer* pointRenderer;
	BoxPrimitive* boxRenderer;
	ParticleSystem* particleSystem;

	void init();
	void run();

	Shader* simpleShader_p;
	Shader* simpleShader_pc;
	Shader* simpleShader_pc_instanced;

private:
	static Game* instance;
	Game(GameType server);
	
    State* currentState;
    PendingState* pendingState;
    RunningState* runningState;
	

    std::map<int, State*> stateLUT; // int is type enum for state hierarchy 
};

